using System;

namespace SmartPeople.Framework.SecuritySpace
{
    public abstract class SecuritySpaceBase : ISecuritySpace
    {
        public void Clear()
        {
            SecurityPermissions.Clear();
            try
            {
                SecuredDocuments.Clear();
            }
            catch (Exception ex)
            {
                throw ex;
            }


            SecuredTypes.Clear();
            Roles.Clear();
            Users.Clear();
        }

        #region CreatePermission

        //TODO:Test this CreatePermission(string roleName, string documentFullName, AccessType accessType)
        public ISecurityPermission CreatePermission(string roleName, string documentFullName, AccessType accessType)
        {
            Guid roleID = Roles.GetRole(roleName).GID;
            Guid docGuid = SecuredDocuments.GetDocument(documentFullName).GID;
            return SecurityPermissions.CreatePermission(roleID, docGuid, accessType);
        }

        //TODO:Test this
        public ISecurityPermission CreatePermission(string roleName, string documentFullName, string actionName,
                                                    AccessType accessType)
        {
            Guid roleGuid = Roles.GetRole(roleName).GID;
            Guid docGuid = SecuredDocuments.GetDocument(documentFullName).GID;
            Guid actionGuid = SecuredDocuments.GetDocument(documentFullName).GetActionID(actionName);
            return SecurityPermissions.CreatePermission(roleGuid, docGuid, actionGuid, accessType);
        }

        //TODO:Test this
        public ISecurityPermission CreatePermission(string roleName, string documentFullName, string actionName,
                                                    string stateName, AccessType accessType)
        {
            Guid roleGuid = Roles.GetRole(roleName).GID;
            Guid docGuid = SecuredDocuments.GetDocument(documentFullName).GID;
            Guid actionGuid = SecuredDocuments.GetDocument(documentFullName).GetActionID(actionName);
            Guid stateGuid = SecuredDocuments.GetDocument(documentFullName).GetStateID(stateName);
            return SecurityPermissions.CreatePermission(roleGuid, docGuid, actionGuid, stateGuid, accessType);
        }

        #endregion

        #region GrantPermission

        public ISecurityPermission GrantPermission(string roleName, string documentFullName)
        {
            return CreatePermission(roleName, documentFullName, AccessType.Allow);
        }

        //TODO:Test this
        public ISecurityPermission GrantPermission(string roleName, string documentFullName, string actionName)
        {
            return CreatePermission(roleName, documentFullName, actionName, AccessType.Allow);
        }

        //TODO:Test this
        public ISecurityPermission GrantPermission(string roleName, string documentFullName, string actionName,
                                                   string stateName)
        {
            return CreatePermission(roleName, documentFullName, actionName, stateName, AccessType.Allow);
        }

        #endregion

        #region DenyPermission

        //TODO:Test this
        public ISecurityPermission DenyPermission(string roleName, string documentFullName)
        {
            return CreatePermission(roleName, documentFullName, AccessType.Deny);
        }

        //TODO:Test this
        public ISecurityPermission DenyPermission(string roleName, string documentFullName, string actionName)
        {
            return CreatePermission(roleName, documentFullName, actionName, AccessType.Deny);
        }

        //TODO:Test this
        public ISecurityPermission DenyPermission(string roleName, string documentFullName, string actionName,
                                                  string stateName)
        {
            return CreatePermission(roleName, documentFullName, actionName, stateName, AccessType.Deny);
        }

        #endregion

        #region RevokePermission

        //TODO:Test this
        public void RevokePermission(string roleName, string documentFullName)
        {
            Guid roleID = Roles.GetRole(roleName).GID;
            Guid documentID = SecuredDocuments.GetDocument(documentFullName).GID;

            SecurityPermissions.RevokePermission(roleID, documentID);
        }

        //TODO:Test this
        public void RevokePermission(string roleName, string documentFullName, string actionName)
        {
            Guid roleID = Roles.GetRole(roleName).GID;
            Guid documentID = SecuredDocuments.GetDocument(documentFullName).GID;
            Guid actionID = SecuredDocuments.GetDocument(documentFullName).GetActionID(actionName);

            SecurityPermissions.RevokePermission(roleID, documentID, actionID);
        }

        //TODO:Test this
        public void RevokePermission(string roleName, string documentFullName, string actionName, string stateName)
        {
            Guid roleID = Roles.GetRole(roleName).GID;
            Guid documentID = SecuredDocuments.GetDocument(documentFullName).GID;
            Guid actionID = SecuredDocuments.GetDocument(documentFullName).GetActionID(actionName);
            Guid stateID = SecuredDocuments.GetDocument(documentFullName).GetStateID(stateName);
            SecurityPermissions.RevokePermission(roleID, documentID, actionID, stateID);
        }

        #endregion

        public abstract Intializer Intializer { get; set; }

        public abstract SecurityUsers Users { get; }

        public abstract SecurityRoles Roles { get; }

        public abstract ISecurityUser CurrentUser { get; set; }

        public abstract SecuritySecuredTypes SecuredTypes { get; }

        public abstract SecuritySecuredDocuments SecuredDocuments { get; }

        public abstract ISecurityPermissions SecurityPermissions { get; }

        #region CurrentUser Checks

        //public bool IsCurrentUserGranted(string objectPath)
        //{
        //    return IsUserGranted(CurrentUser.UserName, objectPath);
        //}

        //public bool IsCurrentUserGranted(string objectPath, string actionName)
        //{
        //    return IsUserGranted(CurrentUser.UserName, objectPath, actionName);
        //}

        //public bool IsCurrentUserGranted(string objectPath, string actionName, string stateName)
        //{
        //    return IsUserGranted(CurrentUser.UserName, objectPath, actionName, stateName);
        //} 

        #endregion

        #region UserChecks

        //TODO:check if current user can check other users Permissions
        public bool IsUserGranted(string userName, string objectPath)
        {
            return IsUserGranted(userName, objectPath, "");
        }

        public bool IsUserGranted(IToken usertoken, string objectPath)
        {
            return IsUserGranted(usertoken, objectPath, "");
        }


        public bool IsUserGranted(IToken usertoken, string objectPath, string actionName)
        {
            return IsUserGranted(usertoken, objectPath, actionName, "");
        }


        public bool IsUserGranted(string userName, string objectPath, string actionName)
        {
            return IsUserGranted(userName, objectPath, actionName, "");
        }


        public bool IsUserGranted(string username, string objectPath, string actionName, string stateName)
        {
            //AccessType accessType = null;
            ISecuritySecuredDocument securedDocument = SecuredDocuments.GetKnownParentPath(objectPath);
            string[] securityRoleNames = Roles.GetRolesForUser(username);
            Guid[] roleIDs = new Guid[securityRoleNames.Length];
            for (int i = 0; i < roleIDs.Length; i++)
            {
                roleIDs[i] = Roles.GetRole(securityRoleNames[i]).GID;
            }
            Guid documentID = securedDocument.GID;
            Guid actionID = securedDocument.GetActionID(actionName);
            Guid stateID = securedDocument.GetStateID(stateName);

            return SecurityPermissions.IsAnyGranted(roleIDs, documentID, actionID, stateID);
        }


        public bool IsUserGranted(IToken usertoken, string objectPath, string actionName, string stateName)
        {
            //AccessType accessType = null;
            ISecuritySecuredDocument securedDocument = SecuredDocuments.GetKnownParentPath(objectPath);
            string[] securityRoleNames = Roles.GetRolesForUser(usertoken);
            Guid[] roleIDs = new Guid[securityRoleNames.Length];
            for (int i = 0; i < roleIDs.Length; i++)
            {
                roleIDs[i] = Roles.GetRole(securityRoleNames[i]).GID;
            }
            Guid documentID = securedDocument.GID;
            Guid actionID = securedDocument.GetActionID(actionName);
            Guid stateID = securedDocument.GetStateID(stateName);

            return SecurityPermissions.IsAnyGranted(roleIDs, documentID, actionID, stateID);
        }

        #endregion

        public bool IsRoleGranted(Guid roleID, Guid documentID, Guid actionID, Guid stateID)
        {
            //return SecurityPermissions.IsGranted(roleID, documentID, actionID, stateID);
            //Guid[] roleIDs=new Guid[]{roleID};
            //return IsGranted(roleIDs, documentID, actionID, stateID);
            throw new NotImplementedException();
        }

        //private bool IsGranted(Guid[] roleIDs, Guid documentID, Guid actionID, Guid stateID)
        //{
        //    return false;
        //}


        //public abstract void Demand(string objectPath, string actionName);

        //public abstract void Demand(string userNname, string objectPath, string actionName);
        //public abstract void Demand(ISecurityUser user, string objectPath, string actionName);
    }
}